home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 7 / Apprentice-Release7.iso / Source Code / C / Applications / Moscow ML 1.42 / src / mosmllib / Word.mlp < prev    next >
Encoding:
Text File  |  1997-08-18  |  4.7 KB  |  156 lines  |  [TEXT/R*ch]

  1. (* Word -- new basis 1994-11-01, 1995-04-06, 1995-07-12, 1996-04-01 *)
  2.  
  3. (* This unit relies on two's complement representation *)
  4.  
  5. type word = word;
  6.  
  7. #include "../config/m.h"
  8. #ifdef SIXTYFOUR
  9. #define WORDSIZE 63
  10. #else
  11. #define WORDSIZE 31
  12. #endif
  13.  
  14. val wordSize = WORDSIZE;
  15.  
  16. local
  17.     prim_val orb_       : word -> word -> word = 2 "or";
  18.     prim_val andb_      : word -> word -> word = 2 "and";
  19.     prim_val xorb_      : word -> word -> word = 2 "xor";
  20.     prim_val lshift_    : word -> word -> word = 2 "shift_left";
  21.     prim_val rshiftsig_ : word -> word -> word = 2 "shift_right_signed";
  22.     prim_val rshiftuns_ : word -> word -> word = 2 "shift_right_unsigned";
  23.  
  24. in
  25.  
  26.     prim_val toInt   : word -> int = 1 "identity";
  27.     prim_val toIntX  : word -> int = 1 "identity";
  28.     prim_val fromInt : int -> word = 1 "identity";
  29.  
  30.     prim_val toLargeInt   : word -> int = 1 "identity";
  31.     prim_val toLargeIntX  : word -> int = 1 "identity";
  32.     prim_val fromLargeInt : int -> word = 1 "identity";
  33.  
  34.     prim_val toLargeWord   : word -> word = 1 "identity";
  35.     prim_val toLargeWordX  : word -> word = 1 "identity";
  36.     prim_val fromLargeWord : word -> word = 1 "identity";
  37.  
  38.     fun orb (x, y)  = orb_ x y;
  39.     fun andb (x, y) = andb_ x y;
  40.     fun xorb (x, y) = xorb_ x y;
  41.     fun notb x      = xorb_ x (fromInt ~1); 
  42.  
  43.  
  44.     fun << (w, k) = 
  45.     if toInt k >= WORDSIZE orelse toInt k < 0 then fromInt 0
  46.     else lshift_ w k;
  47.  
  48.     fun >> (w, k) = 
  49.     if toInt k >= WORDSIZE orelse toInt k < 0 then fromInt 0
  50.     else rshiftuns_ w k;
  51.  
  52.     fun ~>> (w, k) = 
  53.     if toInt k >= WORDSIZE orelse toInt k < 0 then 
  54.         if toInt w >= 0 then    (* msbit = 0 *)
  55.         fromInt 0
  56.         else            (* msbit = 1 *)
  57.         fromInt ~1
  58.     else    
  59.         rshiftsig_ w k;
  60.  
  61.     val op *    : word * word -> word = op *;
  62.     val op +    : word * word -> word = op +;
  63.     val op -    : word * word -> word = op -;
  64.     val op div  : word * word -> word = op div;
  65.     val op mod  : word * word -> word = op mod;
  66.  
  67.     local 
  68.       open StringCvt
  69.       fun skipWSget getc source = getc (dropl Char.isSpace getc source)
  70.  
  71.       (* Below, 48 = Char.ord #"0" and 55 = Char.ord #"A" - 10. *)
  72.       fun decval c = fromInt (Char.ord c) - fromInt 48;
  73.       fun hexval c = 
  74.       if #"0" <= c andalso c <= #"9" then 
  75.           fromInt (Char.ord c) - fromInt 48
  76.       else 
  77.           (fromInt (Char.ord c) - fromInt 55) mod (fromInt 32);
  78.  
  79.       fun prhex i = 
  80.       if toInt i < 10 then Char.chr(toInt (i + fromInt 48))
  81.       else Char.chr(toInt (i + fromInt 55));
  82.  
  83.       fun conv radix i = 
  84.       let fun h n res = 
  85.           if n = fromInt 0 then res
  86.           else h (n div radix) (prhex (n mod radix) :: res)
  87.           fun tostr n = h (n div radix) [prhex (n mod radix)]
  88.       in String.implode (tostr i) end
  89.  
  90.     in
  91.       fun scan radix getc source =
  92.       let open StringCvt
  93.           val source = skipWS getc source
  94.           val (isDigit, factor) = 
  95.           case radix of
  96.               BIN => (fn c => (#"0" <= c andalso c <= #"1"),  2)
  97.             | OCT => (fn c => (#"0" <= c andalso c <= #"7"),  8)
  98.             | DEC => (Char.isDigit,                          10)
  99.             | HEX => (Char.isHexDigit,                       16)
  100.           fun dig1 NONE              = NONE
  101.         | dig1 (SOME (c1, src1)) = 
  102.           let fun digr res src = 
  103.                   case getc src of
  104.                   NONE           => SOME (res, src)
  105.                 | SOME (c, rest) => 
  106.                   if isDigit c then 
  107.                       digr (fromInt factor * res + hexval c) 
  108.                       rest
  109.                   else SOME (res, src)
  110.           in 
  111.               if isDigit c1 then digr (hexval c1) src1 
  112.               else NONE 
  113.           end
  114.           fun getdigs after0 src = 
  115.           case dig1 (getc src) of
  116.               NONE => SOME(fromInt 0, after0)
  117.             | res  => res
  118.           fun hexprefix after0 src =
  119.           if radix <> HEX then getdigs after0 src
  120.           else
  121.               case getc src of
  122.               SOME(#"x", rest) => getdigs after0 rest
  123.             | SOME(#"X", rest) => getdigs after0 rest
  124.             | SOME _           => getdigs after0 src
  125.             | NONE => SOME(fromInt 0, after0)
  126.       in 
  127.           case getc source of
  128.           SOME(#"0", after0) => 
  129.               (case getc after0 of 
  130.                SOME(#"w", src2) => hexprefix after0 src2 
  131.              | SOME _           => hexprefix after0 after0 
  132.              | NONE             => SOME(fromInt 0, after0))
  133.         | SOME _ => dig1 (getc source)
  134.         | NONE   => NONE 
  135.       end;
  136.  
  137.       fun fmt BIN = conv (fromInt  2)
  138.     | fmt OCT = conv (fromInt  8)
  139.     | fmt DEC = conv (fromInt 10)
  140.     | fmt HEX = conv (fromInt 16)
  141.  
  142.       fun toString w   = conv (fromInt 16) w
  143.       fun fromString s = scanString (scan HEX) s
  144.     end (* local for string functions *)
  145.  
  146.     fun min(w1 : word, w2) = if w1 > w2 then w2 else w1;
  147.     fun max(w1 : word, w2) = if w1 > w2 then w1 else w2;
  148.     fun compare (x, y: word) = 
  149.     if x<y then LESS else if x>y then GREATER else EQUAL;
  150.     val op >    : word * word -> bool = op >;
  151.     val op >=   : word * word -> bool = op >=;
  152.     val op <    : word * word -> bool = op <;
  153.     val op <=   : word * word -> bool = op <=;
  154.  
  155. end
  156.